package org.jeecg.modules.demo.pay.controller;


import com.egzosn.pay.common.api.PayConfigStorage;
import com.egzosn.pay.common.bean.PayOutMessage;
import com.egzosn.pay.common.util.str.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;// 日志用了lombok,报错可以将log相关删除
import org.jeecg.common.api.vo.AppleResult;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.base.controller.XuRuiController;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.demo.pay.entity.PayConfig;
import org.jeecg.modules.demo.pay.response.PayResponse;
import org.jeecg.modules.demo.pay.service.IPayConfigService;
import org.jeecg.modules.demo.pay.service.IPayInfoService;
import org.jeecg.modules.demo.pay.util.IosVerifyUtil;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Map;


/**
 * 订单支付
 *
 * @author flyme
 * @date 2019-06-22
 */
@Slf4j
@RestController
@Api(tags = "支付模块-支付管理")
public class PayController extends XuRuiController<PayConfig, IPayConfigService> {

    @Resource
    private IPayConfigService service;

    @Resource
   private IPayInfoService payInfoService;


 /**
     * 获取APP支付预订单信息
     *
     * @return 支付预订单信息
     * @desc 接收参数:payId:支付方式Id,outTradeNo:订单号
     */
    @ApiOperation(value = "获取APP端支付参数", notes = "获取APP支付参数")
    @PostMapping(value = "/pay/mini")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "payId", value = "支付方式ID", paramType = "form"),
        @ApiImplicitParam(name = "outTradeNo", value = "订单号", paramType = "form"),
        @ApiImplicitParam(name = "tradeType", value = "交易类型", paramType = "form")
    })
    public Result<Map<String,Object>> getPayInfoMini(@RequestParam(required = false) Map params) throws IOException {
        return payInfoService.getPayInfo(params, params.getOrDefault("tradeType","JSAPI").toString());
    }


    @ApiOperation(value = "退款", notes = "退款")
    @GetMapping(value = "/pay/refund")
    public Result<Map<String,Object>> payRefund(@RequestParam(required = false) Map params) {
        return payInfoService.getPayInfo(params, "NATIVE");
    }


    /**
     *@param productId 商品ID
     *@param receipt 购买凭证
     */
    @PostMapping(value = "/pay/applepay")
    public AppleResult iosInAppPurchase(@RequestParam(required = false) String productId,@RequestParam(required = false) String receipt) {
        if (StringUtils.isBlank(receipt)){
            return AppleResult.fail("receipt不能为空");
        }
        if (StringUtils.isBlank(productId)){
            return AppleResult.fail("productId不能为空");
        }
        // 0沙盒 非0即线上
        String verifyResult = IosVerifyUtil.buyAppVerify(receipt, 0);
        if (StringUtils.isBlank(verifyResult)) {// 苹果服务器没有返回验证结果
            log.info("IOS内购(充值)=>苹果服务器没有返回验证结果");
            return AppleResult.error("苹果服务器没有返回验证结果");

        } else {// 苹果验证有返回结果
            JSONObject job = JSONObject.parseObject(verifyResult);
            log.info("IOS内购(充值)=>苹果服务器返回验证结果:{}", job);
            String states = job.getString("status");
            //是沙盒环境，应沙盒测试，否则执行下面
            if ("21007".equals(states)) {
                //2.在沙盒测试  发送平台验证
                verifyResult = IosVerifyUtil.buyAppVerify(receipt, 0);
                job = JSONObject.parseObject(verifyResult);
                states = job.getString("status");
            }
            if (states.equals("0")) { // 前端所提供的收据是有效的    验证成功
                String r_receipt = job.getString("receipt");
                JSONObject returnJson = JSONObject.parseObject(r_receipt);
                String in_app = returnJson.getString("in_app");
                JSONArray jsonArray = JSONArray.parseArray(in_app);
                log.info("IOS内购(充值)=>苹果服务器返回验证结果订单数量:{}", jsonArray.size());
                for (int i = 0; i < jsonArray.size(); i++) {
                    if (productId.equals(jsonArray.getJSONObject(i).get("product_id") == null ? null : jsonArray.getJSONObject(i).get("product_id").toString())) {
                        // 订单号
                        String transactionId = jsonArray.getJSONObject(i).get("transaction_id") == null ? null : jsonArray.getJSONObject(i).get("transaction_id").toString();
                        //TODO
                        /* 自己的业务处理 */
                        // 1.创建支付信息

                        // 2. 修改订单信息

                    }
                }
            } else {
                return AppleResult.error(job);
            }
        }
        return AppleResult.success();
    }
    /**
     * 支付回调地址
     */
    @PostMapping(value = "/common/payBack/{handlerName}/{companyId}/{payId}")
    public String payBack(HttpServletRequest request, @PathVariable String payId, @PathVariable Long companyId, @PathVariable String handlerName) throws IOException {
        request.getSession().setAttribute("companyId",companyId);
        log.debug("支付回调入口"+payId);
        PayResponse payResponse = service.getPayResponse(payId, handlerName);
        log.debug("支付回调入对象"+payResponse);
        PayConfigStorage storage = payResponse.getStorage();
        Map<String, Object> params = payResponse.getService().getParameter2Map(request.getParameterMap(), request.getInputStream());
        log.debug("支付回调params"+params);
        if (null == params) {
            log.debug("params为空");
            return payResponse.getService().getPayOutMessage("fail", "失败").toMessage();
        }
        //退款通知也走这个接口，所以判断如果是退款的话不校验参数
        if(oConvertUtils.isNotEmpty(params.get("req_info"))){
            log.debug("有req_info参数，退款通知接口");
            PayOutMessage outMessage = payResponse.getRouter().route(params, storage);
            return outMessage.toMessage();
        }
        //校验
        if (payResponse.getService().verify(params)) {
            PayOutMessage outMessage = payResponse.getRouter().route(params, storage);
            return outMessage.toMessage();
        }else{
            log.debug("验签失败");
        }
        return payResponse.getService().getPayOutMessage("fail", "失败").toMessage();
    }

    /**
     * 退款回调地址
     */
    @Transactional
    @PostMapping(value = "/common/refundBack/{handlerName}/{companyId}/{payId}")
    public String refundBack(HttpServletRequest request, @PathVariable String payId, @PathVariable Long companyId, @PathVariable String handlerName) throws IOException {
        request.getSession().setAttribute("companyId",companyId);
        log.debug("退款回调入口"+payId);
        PayResponse payResponse = service.getPayResponse(payId, handlerName);
        log.debug("退款回调入对象"+payResponse);
        PayConfigStorage storage = payResponse.getStorage();
        Map<String, Object> params = payResponse.getService().getParameter2Map(request.getParameterMap(), request.getInputStream());
        log.debug("退款回调params"+params);
        if (null == params) {
            log.debug("params为空");
            return payResponse.getService().getPayOutMessage("fail", "失败").toMessage();
        }
        PayOutMessage outMessage = payResponse.getRouter().route(params, storage);
        if(outMessage!=null){
            return outMessage.toMessage();
        }else{
            return payResponse.getService().getPayOutMessage("fail", "失败").toMessage();
        }
    }
}
